package api

import (
	"fmt"
	"ginfast/pkg/ginx"
	"sync"

	"github.com/silenceper/wechat/v2"
	"github.com/silenceper/wechat/v2/cache"
	offConfig "github.com/silenceper/wechat/v2/officialaccount/config"
	"github.com/silenceper/wechat/v2/officialaccount/message"
)

type officMessage struct {
	Signature   string `form:"signature" binding:"required"`
	Timestamp   string `form:"timestamp" binding:"required"`
	Nonce       string `form:"nonce" binding:"required"`
	EncryptType string `form:"encrypt_type" binding:"required"`
}

type official struct {
	Cfg  *offConfig.Config
	Wc   *wechat.Wechat
	Once sync.Once
}

var gOffic official

type WeChatConfig struct {
	AppID          string `json:"appId"`
	AppSecret      string `json:"appSecret"`
	Token          string `json:"token"`
	EncodingAESKey string `json:"encodingAESKey"`
}

// OfficeMsgHandler 消息处理
func OfficialMsgHandler(c *ginx.Context) {
	gOffic.Once.Do(func() {
		var cfg WeChatConfig
		gOffic.Wc = wechat.NewWechat()
		//这里本地内存保存access_token，也可选择redis，memcache或者自定cache
		memory := cache.NewMemory()
		gOffic.Cfg = &offConfig.Config{
			AppID:     cfg.AppID,
			AppSecret: cfg.AppSecret,
			Token:     cfg.Token,
			Cache:     memory,
		}
		if cfg.EncodingAESKey != "" {
			gOffic.Cfg.EncodingAESKey = cfg.EncodingAESKey
		}
	})
	var param officMessage
	//获取参数
	if err := c.ShouldBind(&param); err != nil {
		c.JSONWriteError(err)
		return
	}
	officialAccount := gOffic.Wc.GetOfficialAccount(gOffic.Cfg)
	// 传入request和responseWriter
	server := officialAccount.GetServer(c.Request, c.Writer)
	//设置接收消息的处理方法
	server.SetMessageHandler(msgHandler)
	//处理消息接收以及回复
	err := server.Serve()
	if err != nil {
		fmt.Println(err)
		return
	}
	//发送回复的消息
	server.Send()
}

// msgHandler 公众号消息
func msgHandler(msg *message.MixMessage) *message.Reply {
	//TODO
	switch msg.MsgType {
	case message.MsgTypeText:
	case message.MsgTypeEvent:
		switch msg.Event {
		case "subscribe":
			// msg.FromUserName
		case "unsubscribe":
		}
	default:
	}
	//回复消息：演示回复用户发送的消息
	text := message.NewText(msg.Content)
	return &message.Reply{MsgType: message.MsgTypeText, MsgData: text}
}
